package top.tenebrous.termbor.rpc.serialization.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import top.tenebrous.termbor.rpc.common.utils.SerializationUtils;
import top.tenebrous.termbor.rpc.protocol.RpcProtocol;
import top.tenebrous.termbor.rpc.protocol.header.RpcHeader;
import top.tenebrous.termbor.rpc.serialization.Serialization;

import java.nio.charset.StandardCharsets;

/**
 * @program: termbor-rpc
 * @description:
 * @author: yazhang6
 * @create: 2024-05-21 10:37
 **/
public class RpcEncoder extends MessageToByteEncoder<RpcProtocol<Object>> implements RpcCodec {

    @Override
    protected void encode(ChannelHandlerContext ctx, RpcProtocol<Object> msg,
        ByteBuf byteBuf) throws Exception {
        RpcHeader header = msg.getHeader();
        byteBuf.writeShort(header.getMagic());
        byteBuf.writeByte(header.getMsgType());
        byteBuf.writeByte(header.getStatus());
        byteBuf.writeLong(header.getRequestId());
        String serializationType = header.getSerializationType();
        // TODO serialization是扩展点
        Serialization serialization = getSerialization(serializationType);
        byteBuf.writeBytes(SerializationUtils.getPaddingString(serializationType).getBytes(StandardCharsets.UTF_8));
        byte[] data = serialization.serialize(msg.getBody());
        byteBuf.writeInt(data.length);
        byteBuf.writeBytes(data);
        //异步调用流控分析后置处理器
        header.setMsgLen(data.length);
    }

}
